package com.zha.config;

import com.zha.constant.BusinessEnum;
import com.zha.constant.ResourceConstants;
import com.zha.filter.TokenTranslationFilter;
import com.zha.model.Result;
import com.zha.util.JSONUtils;
import com.zha.util.ResponseUtils;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * @Title: 只有光头才能变强
 * @Author: 炸炸
 * @Date: 2024/12/11 16:23
 * security安全框架的资源服务器配置类
 */
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class ResourceServerConfig  {

    @Resource
    public TokenTranslationFilter tokenTranslationFilter;
    /**
     * 设置security相关http设置
     */
    /*@Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // 关闭跨站请求
        http.cors().disable();
        // 关闭跨域请求
        http.csrf().disable();
        // 关闭session使用策略
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        // 添加一个token转换过滤器在security安全框架的认证用户身份信息的过滤器之前
        http.addFilterBefore(tokenTranslationFilter, UsernamePasswordAuthenticationFilter.class);
        http.authorizeHttpRequests(authorize ->
                        authorize
                                // 放行白名单路径，例如：
                                .requestMatchers(ResourceConstants.RESOURCE_ALLOW_URLS).permitAll()  // 允许所有用户访问这些路径
                                // 其他的请求需要身份认证
                                .anyRequest().authenticated()  // 所有其他请求都需要身份认证
                )
                // 异步的处理
                .exceptionHandling(exceptionHandling ->
                        exceptionHandling
                                .accessDeniedHandler(accessDeniedHandler())  // 处理请求携带token但是权限不足的情况
                                .authenticationEntryPoint(authenticationEntryPoint()) // 处理未携带token的情况
                );

        return http.build();
    }
*/
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http
                // 关闭跨站请求
                .cors(AbstractHttpConfigurer::disable)
                // 关闭跨域请求
                .csrf(AbstractHttpConfigurer::disable)
                // 关闭session使用策略
                .sessionManagement(session -> session
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                // 添加一个token转换过滤器在security安全框架的认证用户身份信息的过滤器之前
                .addFilterBefore(tokenTranslationFilter, UsernamePasswordAuthenticationFilter.class)
                // 配置请求授权规则
                .authorizeHttpRequests(authorize -> authorize
                        .requestMatchers(ResourceConstants.RESOURCE_ALLOW_URLS).permitAll()  // 放行白名单路径，允许所有用户访问这些路径
                        .anyRequest().authenticated()) // 所有其他请求都需要身份认证
                // 异常的处理
                .exceptionHandling(exceptionHandling -> exceptionHandling
                        .accessDeniedHandler(accessDeniedHandler())  // 处理请求携带token但是权限不足的情况
                        .authenticationEntryPoint(authenticationEntryPoint())) // 处理未携带token的情况

                .build();
    }
    /**
     * 处理请求携带token但是权限不足的情况处理器
     * @return
     */
    @Bean
    public AccessDeniedHandler accessDeniedHandler() {
        return (request, response, accessDeniedException) -> {
            // 创建统一响应结果对象
            Result<Object> result = Result.fail(BusinessEnum.ACCESS_DENY);
            // 响应结果给前端
            ResponseUtils.write(response, JSONUtils.toJson(result));
        };
    }

    /**
     * 处理未携带token的情况处理器
     * @return
     */
    @Bean
    public AuthenticationEntryPoint authenticationEntryPoint() {
        return (request, response, authException) -> {
            // 创建统一响应结果对象
            Result<Object> result = Result.fail(BusinessEnum.UN_AUTHORIZATION);
            // 响应结果给前端
            ResponseUtils.write(response, JSONUtils.toJson(result));
        };
    }
}
